<?php
class cb_Request_Object {
	
    const SCHEME_HTTP  = 'http';
    
    const SCHEME_HTTPS = 'https';

    /**
     * 参数范围
     * @var array
     */
    var $_paramSources = array('_GET', '_POST');

    /**
     * 请求_URI
     * @var string;
     */
    var $_requestUri;

    /**
     * Base URL
     * @var string
     */
    var $_baseUrl = null;

    /**
     * Base path
     * @var string
     */
    var $_basePath = null;

    /**
     * PATH_INFO
     * @var string
     */
    var $_pathInfo = '';
    
	/**
     * 是否分发完成
     * @var boolean
     */
    var $_dispatched = false;

    /**
     * 模块名称,从参数中获取(前台）
     * @var string
     */
    var $_module;
    
    /**
     * 控制器名称,从参数中获取(后台）
     * @var string
     */
    var $_controller;
    
    /**
     * 动作名称,从参数中获取
     * @var string
     */
    var $_action;

    /**
     * 所有请求的参数
     * @var array
     */
    var $_params = array();
    
	function __construct() {
		$this->setRequestUri();
		register_shutdown_function(array(&$this, "__destruct"));
	}
    
	function get($key)
    {
        switch (true) {
            case isset($this->_params[$key]):
                return $this->_params[$key];
            case isset($_GET[$key]):
                return $_GET[$key];
            case isset($_POST[$key]):
                return $_POST[$key];
            case isset($_COOKIE[$key]):
                return $_COOKIE[$key];
            case ($key == 'REQUEST_URI'):
                return $this->getRequestUri();
            case ($key == 'PATH_INFO'):
                return $this->getPathInfo();
            case isset($_SERVER[$key]):
                return $_SERVER[$key];
            case isset($_ENV[$key]):
                return $_ENV[$key];
            default:
                return null;
        }
    }
    
    /**
     * 设置 REQUEST_URI
     *
     * 如果没有值被传递, 则使用 $_SERVER['REQUEST_URI'],
     * $_SERVER['HTTP_X_REWRITE_URL'], or $_SERVER['ORIG_PATH_INFO'] + $_SERVER['QUERY_STRING'].
     *
     * @param string $requestUri
     * @return
     */
    function setRequestUri($requestUri = null)
    {
        if ($requestUri === null) {
            if (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
                $requestUri = $_SERVER['HTTP_X_REWRITE_URL'];
            } elseif (isset($_SERVER['REQUEST_URI'])) {
                $requestUri = $_SERVER['REQUEST_URI'];
                if (isset($_SERVER['HTTP_HOST']) && strstr($requestUri, $_SERVER['HTTP_HOST'])) {
                	$parsed = parse_url($requestUri);
                    $pathInfo    = $parsed['path'];
                    $queryString = $parsed['query'];
                    $requestUri  = $pathInfo
                                 . ((empty($queryString)) ? '' : '?' . $queryString);
                }
            } elseif (isset($_SERVER['ORIG_PATH_INFO'])) { // IIS 5.0, PHP as CGI
                $requestUri = $_SERVER['ORIG_PATH_INFO'];
                if (!empty($_SERVER['QUERY_STRING'])) {
                    $requestUri .= '?' . $_SERVER['QUERY_STRING'];
                }
            } else {
                return null;
            }
        } elseif (!is_string($requestUri)) {
            return null;
        } else {
            if (false !== ($pos = strpos($requestUri, '?'))) {
                $query = substr($requestUri, $pos + 1);
                parse_str($query, $vars);
                $this->setQuery($vars);
            }
        }

        $this->_requestUri = $requestUri;
    }

    /**
     * 设置GET值
     *
     * @param  string|array $spec
     * @param  null|mixed $value
     * @return
     */
    public function setQuery($spec, $value = null)
    {
        if ((null === $value) && !is_array($spec)) {
        	return false;
        }
        if ((null === $value) && is_array($spec)) {
            foreach ($spec as $key => $value) {
                $this->setQuery($key, $value);
            }
            return $this;
        }
        $_GET[(string) $spec] = $value;
        return $this;
    }
    /**
     * 返回 REQUEST_URI
     *
     * @return string
     */
    public function getRequestUri()
    {
        if (empty($this->_requestUri)) {
            $this->setRequestUri();
        }

        return $this->_requestUri;
    }

    /**
     * 设置 BASE_URL
     *
     * 例如:
     * - /admin
     * - /subdir/index.php
     *
     * @param mixed $baseUrl
     * @return bool
     */
    public function setBaseUrl($baseUrl = null)
    {
        if ((null !== $baseUrl) && !is_string($baseUrl)) {
            return false;
        }

        if ($baseUrl === null) {
            $filename = (isset($_SERVER['SCRIPT_FILENAME'])) ? basename($_SERVER['SCRIPT_FILENAME']) : '';

            if (isset($_SERVER['SCRIPT_NAME']) && basename($_SERVER['SCRIPT_NAME']) === $filename) {
                $baseUrl = $_SERVER['SCRIPT_NAME'];
            } elseif (isset($_SERVER['PHP_SELF']) && basename($_SERVER['PHP_SELF']) === $filename) {
                $baseUrl = $_SERVER['PHP_SELF'];
            } elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $filename) {
                $baseUrl = $_SERVER['ORIG_SCRIPT_NAME'];
            } else {
                $path    = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : '';
                $file    = isset($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : '';
                $segs    = explode('/', trim($file, '/'));
                $segs    = array_reverse($segs);
                $index   = 0;
                $last    = count($segs);
                $baseUrl = '';
                do {
                    $seg     = $segs[$index];
                    $baseUrl = '/' . $seg . $baseUrl;
                    ++$index;
                } while (($last > $index) && (false !== ($pos = strpos($path, $baseUrl))) && (0 != $pos));
            }

            $requestUri = $this->getRequestUri();

            if (0 === strpos($requestUri, $baseUrl)) {
                $this->_baseUrl = $baseUrl;
                return true;
            }

            if (0 === strpos($requestUri, dirname($baseUrl))) {
                $this->_baseUrl = rtrim(dirname($baseUrl), '/');
                return true;
            }

            if (!strpos($requestUri, basename($baseUrl))) {
                $this->_baseUrl = '';
                return true;
            }

            // 如果使用 mod_rewrite 或 ISAPI_Rewrite 隐藏了BASE_URL的文件名 ，
            //  则$pos !== 0 用来确定其不会匹配 PATH_INFO 或 QUERY_STRING
            if ((strlen($requestUri) >= strlen($baseUrl))
                && ((false !== ($pos = strpos($requestUri, $baseUrl))) && ($pos !== 0)))
            {
                $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
            }
        }

        $this->_baseUrl = rtrim($baseUrl, '/');
        return true;
    }

    /**
     * 获取 REQUEST_URI里 PATH_INFO之前的所有东西
     * <form action="<?=$baseUrl?>/news/submit" method="POST"/>
     *
     * @return string
     */
    public function getBaseUrl()
    {
        if (null === $this->_baseUrl) {
            $this->setBaseUrl();
        }

        return $this->_baseUrl;
    }

    /**
     * 设置URL的base path
     *
     * @param string|null $basePath
     * @return bool
     */
    public function setBasePath($basePath = null)
    {
        if ($basePath === null) {
            $filename = basename($_SERVER['SCRIPT_FILENAME']);

            $baseUrl = $this->getBaseUrl();
            if (empty($baseUrl)) {
                $this->_basePath = '';
                return true;
            }

            if (basename($baseUrl) === $filename) {
                $basePath = dirname($baseUrl);
            } else {
                $basePath = $baseUrl;
            }
        }
        
        if (substr(PHP_OS, 0, 3) === 'WIN') {
            $basePath = str_replace('\\', '/', $basePath);
        }

        $this->_basePath = rtrim($basePath, '/');
        return true;
    }

    /**
     * 获取 REQUEST_URI里 PATH_INFO之前的所有东西,但不包括文件名
     * <img src="<?=$basePath?>/images/zend.png"/>
     *
     * @return string
     */
    public function getBasePath()
    {
        if (null === $this->_basePath) {
            $this->setBasePath();
        }

        return $this->_basePath;
    }

    /**
     * 设置 PATH_INFO 串
     *
     * @param string|null $pathInfo
     * @return bool
     */
    function setPathInfo($pathInfo = null)
    {
        if ($pathInfo === null) {
            $baseUrl = $this->getBaseUrl();

            if (null === ($requestUri = $this->getRequestUri())) {
                return false;
            }
            
            $pos = strpos($requestUri, '?');
            if ($pos) {
                $requestUri = substr($requestUri, 0, $pos);
            }

            if ((null !== $baseUrl)
                && (false === ($pathInfo = substr($requestUri, strlen($baseUrl)))))
            {
                // If substr() returns false then PATH_INFO is set to an empty string
                $pathInfo = '';
            } elseif (null === $baseUrl) {
                $pathInfo = $requestUri;
            }
        }

        $this->_pathInfo = (string) $pathInfo;
        return true;
    }

    /**
     * 返回 BaseUrl 和 QueryString之间的的所有东西.
     *
     * @return string
     */
    function getPathInfo()
    {
        if (empty($this->_pathInfo)) {
            $this->setPathInfo();
        }

        return $this->_pathInfo;
    }

    /**
     * 设置参数允许的范围
     *
     * 不能是空数组，或多个 '_GET'， '_POST'.
     *
     * @param  array $paramSoures
     * @return bool
     */
    function setParamSources($paramSources = array())
    {
        $this->_paramSources = $paramSources;
        return true;
    }

    /**
     * 获取参数允许的范围
     *
     * @return array
     */
    function getParamSources()
    {
        return $this->_paramSources;
    }
    
    /**
     * 获取模块Id
     *
     * @return string
     */
    function getModuleId()
    {
        if (null === $this->_module) {
            $this->_module = $this->getParam('module');
        }

        return $this->_module;
    }

    /**
     * 设置模块Id
     *
     * @param string $value
     */
    function setModuleId($value)
    {
        $this->_module = $value;
        return $this->_module;
    }
    
    
    /**
     * 获取控制器名称
     *
     * @return string
     */
    function getControllerName()
    {
        if (null === $this->_controller) {
            $this->_controller = $this->getParam('controller');
        }

        return $this->_controller;
    }

    /**
     * 设置控制器名称
     *
     * @param string $value
     */
    function setControllerName($value)
    {
        $this->_controller = $value;
        return $this->_controller;
    }

    /**
     * 获取动作名称
     *
     * @return string
     */
    function getActionName()
    {
        if (null === $this->_action) {
            $this->_action = strtolower($this->getParam('action'));
        }

        return $this->_action;
    }

    /**
     * 设置动作名称
     *
     * @param string $value
     */
    function setActionName($value)
    {
        $this->_action = $value;
        if (null === $value) {
            $this->setParam('action', $value);
        }
        return $this->_action;
    }

    /**
     * 获取一个参数
     *
     * @param string $key
     * @param mixed $default
     * @return mixed
     */
    function getParam($key, $default = null)
    {
    	$keyName = (string)$key;

        $paramSources = $this->getParamSources();
        if (isset($this->_params[$keyName])) {
            return $this->_params[$keyName];
        } elseif (in_array('_GET', $paramSources) && (isset($_GET[$keyName]))) {
            return $_GET[$keyName];
        } elseif (in_array('_POST', $paramSources) && (isset($_POST[$keyName]))) {
            return $_POST[$keyName];
        }

        return $default;
    }

    /**
     * 设置一个参数
     *
     * 如果 $value 为 null 的话，将删除该参数
     *
     * @param string $key
     * @param mixed $value
     * @return bool
     */
    function setParam($key, $value)
    {
        $key = (string) $key;

        if ((null === $value) && isset($this->_params[$key])) {
            unset($this->_params[$key]);
        } elseif (null !== $value) {
            $this->_params[$key] = $value;
        }

        return true;
    }

    /**
     * 获取所有
     *
     * @return array
     */
     function getParams()
     {
        $return = $this->_params;
        if (isset($_GET) && is_array($_GET)) {
            $return += $_GET;
        }
        if (isset($_POST) && is_array($_POST)) {
            $return += $_POST;
        }
        return $return;
     }

    /**
     * 批量设置参数
     *
     * @param array $array
     * @return bool
     */
    function setParams(array $array)
    {
        $this->_params = $this->_params + (array) $array;

        foreach ($this->_params as $key => $value) {
            if (null === $value) {
                unset($this->_params[$key]);
            }
        }
    }

    /**
     * 设置分发标志
     *
     * @param boolean $flag
     * @return Zend_Controller_Request_Abstract
     */
    function setDispatched($flag = true)
    {
        $this->_dispatched = $flag ? true : false;
        return $this->_dispatched;
    }

    /**
     * 返回请求是否已经分发
     *
     * @return boolean
     */
    function isDispatched()
    {
        return $this->_dispatched;
    }

	function header($url='.'){
		header("Location:$url");
	}

    function getServer ($key = null, $default = null)
    {
        if (null === $key) {
            return $_SERVER;
        }
        return (isset($_SERVER[$key])) ? $_SERVER[$key] : $default;
    }

    function getEnv ($key = null, $default = null)
    {
        if (null === $key) {
            return $_ENV;
        }
        return (isset($_ENV[$key])) ? $_ENV[$key] : $default;
    }

    function getMethod ()
    {
        return $this->getServer('REQUEST_METHOD');
    }

    function isPost ()
    {
        if ('POST' == $this->getMethod()) {
            return true;
        }
        return false;
    }

    function isGet ()
    {
        if ('GET' == $this->getMethod()) {
            return true;
        }
        return false;
    }

    function isXmlHttpRequest ()
    {
        return ($this->getHeader('X_REQUESTED_WITH') == 'XMLHttpRequest');
    }

    function getHeader ($header)
    {
        if (empty($header)) {
            die('An HTTP header name is required');
        }
        $temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
        if (! empty($_SERVER[$temp])) {
            return $_SERVER[$temp];
        }
        if (function_exists('apache_request_headers')) {
            $headers = apache_request_headers();
            if (! empty($headers[$header])) {
                return $headers[$header];
            }
        }
        return false;
    }

    function getPost ($name=null, $default = null)
    {
    	if(null === $name){
    		return $_POST;
    	}
        return isset($_POST[$name]) ? $_POST[$name] : $default;
    }

    function getQuery ($name=null, $default = null)
    {
    	if(null === $name){
    		return $_GET;
    	}
        return isset($_GET[$name]) ? $_GET[$name] : $default;
    }

    function getCookie($key = null, $default = null)
    {
        if (null === $key) {
            return $_COOKIE;
        }

        return (isset($_COOKIE[$key])) ? $_COOKIE[$key] : $default;
    }
    
    /**
     * 获取主机名，包括端口号
     *
     * @return string
     */
    function getHttpHost()
    {
        $host = $this->getServer('HTTP_HOST');
        if (!empty($host)) {
            return $host;
        }
        
        $scheme = $this->getScheme();
        $name   = $this->getServer('SERVER_NAME');
        $port   = $this->getServer('SERVER_PORT');

        if (($scheme == self::SCHEME_HTTP && $port == 80) || ($scheme == self::SCHEME_HTTPS && $port == 443)) {
            return $name;
        } else {
            return $name . ':' . $port;
        }
    }

    /**
     * 获取SCHEME
     */
    function getScheme()
    {
        return ($this->getServer('HTTPS') == 'on') ? self::SCHEME_HTTPS : self::SCHEME_HTTP;
    }
    
    /**
     * 获取当前完整URL地址
     */
    function getCurrentUrl(){
    	$current_url = $this->getScheme();
    	$current_url.= '://';
    	$current_url.= $_SERVER ['HTTP_HOST'];
    	$current_url.= $this->getRequestUri();
    	return $current_url;
    }
    
    /**
     * 获取站点首页URL地址
     */
    function getIndexUrl(){
    	$index_url = $this->getScheme();
    	$index_url.= '://';
    	$index_url.= $_SERVER ['HTTP_HOST'];
    	$index_url.= INSTALL_PATH;
    	return $index_url;
    }
    
    /**
     * 获取站内来源
     */
    function getReffer(){
    	$reffer = isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:"";
    	if(!strpos($reffer,$this->getHttpHost())){
    		$reffer = '';
    	}
    	return $reffer;
    }
    
	function __destruct() {
		return true;
	}
}